/******************************************************************************
 *
 * MotionViewer
 * Copyright (C) 2007 Sangyoon Lee, Electronic Visualization Laboratory, 
 * University of Illinois at Chicago
 *
 * This software is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either Version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser Public License along
 * with this software; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Questions or comments about MotionViewer should be directed to 
 * cavern@evl.uic.edu
 *
 *****************************************************************************/
#include <ogreplatform.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <Carbon/Carbon.h>
#endif

#include "ViconVisualizer.h"
#include "ViconMotionDataSet.h"


ViconVisualizer::ViconVisualizer(SceneManager* mgr, SceneNode* head)
{
	static int g_VVID = -1;
	m_iUID = ++g_VVID;
	m_iMarkers = 0;
	m_iBodies = 0;
	m_bMarkerVisibility = true;
	m_bBodyVisibility = true;

	m_pSceneMgr = mgr;
	m_pHeadNode = head;

	m_pDataSet = NULL;

	char nodestr[64];
	sprintf(nodestr, "viconVisualizer_%i", m_iUID);
	m_pBaseNode = m_pHeadNode->createChildSceneNode(nodestr);

	// create material
	char markermat[24];
	char bodymat[24];
	sprintf(markermat, "mocapMarkerMat_%i", m_iUID);
	sprintf(bodymat, "mocapBodyMat_%i", m_iUID);
	
	// marker material
	m_pMarkerMaterial = MaterialManager::getSingleton().create(markermat,"mocapVisualizer"); 
	m_pMarkerMaterial->setReceiveShadows(false); 
	m_pMarkerMaterial->getTechnique(0)->setLightingEnabled(true); 
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.9,0.5,0.0,1.0); 
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setAmbient(0.9,0.5,0.0); 
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(0.9,0.5,0.0);
	
	// body material
	m_pBodyMaterial = MaterialManager::getSingleton().create(bodymat,"mocapVisualizer"); 
	m_pBodyMaterial->setReceiveShadows(false); 
	m_pBodyMaterial->getTechnique(0)->setLightingEnabled(true); 
	m_pBodyMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.1,0.1,0.1,0.1); 
	m_pBodyMaterial->getTechnique(0)->getPass(0)->setAmbient(0.2,0.5,0.8);
}

ViconVisualizer::~ViconVisualizer()
{
}

void ViconVisualizer::createScene(char* source)
{
}

void ViconVisualizer::resetScene()
{
}

void ViconVisualizer::update(float addedTime)
{
}

void ViconVisualizer::setDebug(bool debug)
{
	m_pDataSet->setDebug(debug);
}

std::string ViconVisualizer::getDebugBodyInfo()
{
	return m_pDataSet->getDebugBodyInfo();
}

std::string ViconVisualizer::getDebugMarkerInfo()
{
	return m_pDataSet->getDebugMarkerInfo();
}

void ViconVisualizer::setMarkerVisible(bool vis)
{
	if (m_bMarkerVisibility == vis)
		return;

	m_bMarkerVisibility = vis;

	for (int i=0; i<m_iMarkers; i++)
		m_vMarkerNodes[i]->setVisible(m_bMarkerVisibility);
}

void ViconVisualizer::setBodyVisible(bool vis)
{
	if (m_bBodyVisibility == vis)
		return;

	m_bBodyVisibility = vis;

	for (int i=0; i<m_iBodies; i++)
	{
		m_vBodies[i]->pNode->setVisible(m_bBodyVisibility);
	}
}

void ViconVisualizer::setBodyDrawingTypes(tagBODY_TYPE type, bool value)
{
	if (m_iBodies < 1)
		return;

	switch(type)
	{
	case BT_NONE:
		break;
	case BT_BODY:
		for (int i=0; i<m_iBodies; i++)
			m_vBodies[i]->pEnt->setVisible(value);
		break;
	case BT_AXIS:
		for (int i=0; i<m_iBodies; i++)
			m_vBodies[i]->pAxis->setVisible(value);
		break;
	case BT_ALL:
		for (int i=0; i<m_iBodies; i++)
		{
			m_vBodies[i]->pEnt->setVisible(value);
			m_vBodies[i]->pAxis->setVisible(value);
			m_vBodies[i]->pNode->setVisible(value);
			m_bBodyVisibility = value;
		}
		break;
	}
}

void ViconVisualizer::toggleBodyDrawingTypes(tagBODY_TYPE type)
{
	if (m_iBodies < 1)
		return;

	switch(type)
	{
	case BT_NONE:
		break;
	case BT_BODY:
		if (m_vBodies[0]->pEnt->isVisible())
			setBodyDrawingTypes(type, false);
		else
			setBodyDrawingTypes(type, true);
		break;
	case BT_AXIS:
		if (m_vBodies[0]->pAxis->isVisible())
			setBodyDrawingTypes(type, false);
		else
			setBodyDrawingTypes(type, true);
		break;
	case BT_ALL:
		break;
	}
}

void ViconVisualizer::setPosition(float x, float y, float z)
{
	if(m_pBaseNode)
		m_pBaseNode->setPosition(x, y, z);
}

void ViconVisualizer::setMarkerColor(float r, float g, float b, float a)
{
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setDiffuse(r,g,b,a); 
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setAmbient(r,g,b); 
	m_pMarkerMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(r,g,b);
}

void ViconVisualizer::setBodyColor(float r, float g, float b, float a)
{
	m_pBodyMaterial->getTechnique(0)->getPass(0)->setDiffuse(r,g,b,a); 
	m_pBodyMaterial->getTechnique(0)->getPass(0)->setAmbient(r,g,b); 
}

const ColourValue& ViconVisualizer::getMarkerColor()
{
	return m_pMarkerMaterial->getTechnique(0)->getPass(0)->getDiffuse();
}

const ColourValue& ViconVisualizer::getBodyColor()
{
	return m_pBodyMaterial->getTechnique(0)->getPass(0)->getDiffuse();
}

void ViconVisualizer::getPosition(float* pos)
{
	if(m_pBaseNode)
	{	
		Ogre::Vector3 vec = m_pBaseNode->getPosition();
		pos[0] = vec[0];
		pos[1] = vec[1];
		pos[2] = vec[2];
	}
	else
	{
		pos[0] = 0;
		pos[1] = 0;
		pos[2] = 0;
	}
}